import timber.ui.ProgressIndicator;

/**
	LoadView loads swf or jpeg (or png, and gif in flash 8) with progress indicators.
	
	Also provides some handy things like size and scale adjustments.
	Broadcasts an onLoad message when the asset is loaded.

	@author Chandler McWilliams
	@version 2006-02-16
*/


dynamic class timber.ui.LoadView extends MovieClip
{
	
	private var loader;
	private var theurl;
	private var progress_mc;
	private var img_mc = false;
	private var type = false;
	
	private var resize_max = false;
	private var resize_crop = false;

	private var autoCenter:Boolean = false;
	
// ===========================================================
// - CONSTRUCTOR
// ===========================================================
	public function LoadView() {
		AsBroadcaster.initialize(this);
		loader = new MovieClipLoader();
		loader.addListener(this);
	}
	

// ===========================================================
// - ACCESSORS
// ===========================================================
	/**
		Returns the url of the content loaded by this clip

		@return String
	*/
	public function getContentURL() {
		return theurl;
	}

	/**
		Returns true if the assets is wider than it is tall

		@return Boolean
	*/
	public function isLandscape() {
		return getWidth() > getHeight();
	}
	
	/**
		Gets the width

		@return Number
	*/
	public function getWidth() {return _width;}
	
	/**
		Sets the width

		@param  val new width
		@return void
	*/
	public function setWidth(val) { _width = val; }
	
	/**
		Get height

		@return Number
	*/
	public function getHeight() {return _height;}
	
	/**
		Set the height.

		@param  val new height
		@return void
	*/
	public function setHeight(val) { _height = val; }
	
	/**
		Returns true if the asset is a swf.

		@return Boolean
	*/
	public function isSWF():Boolean	{ return (type.toLowerCase() == 'swf');	}

	/**
		Returns true if the asset is a jpg.

		@return Boolean
	*/
	public function isJPG():Boolean	{ return (type.toLowerCase() == 'jpg');	}
	public function isJPEG():Boolean	{ return isJPG();	}

	/**
		Returns true if the asset is a gif.

		@return Boolean
	*/
	public function isGIF():Boolean	{ return (type.toLowerCase() == 'gif');	}

	/**
		Returns true if the asset is a png.

		@return Boolean
	*/
	public function isPNG():Boolean	{ return (type.toLowerCase() == 'png');	}
	
	/**
		Returns the mc used for a progress indicator

		@return MovieClip
	*/
	public function getProgressClip() {return progress_mc;}
	
	/**
		Sets the clip to use for a progress indicator.

		@param  val new ProgressIndicator clip
	*/
	public function setProgressClip(val:ProgressIndicator) {progress_mc = val;}
	
	/**
		Sets the autoCenter setting.

	*/
	public function setAutoCenter(val) {autoCenter = val;}

	/**
		Get the content clip
	*/
	public function get content() {return img_mc;}


// ===========================================================
// - IMAGE MANIPULATION
// ===========================================================
	/**
		Proportionally scales a movieclip to a max width and height.
		Fits whichever is smaller.

		@param  width Maximum width.
		@param  height Maximum height.
	*/
	public function setMaxSize(width, height, scale_up) {
		if (arguments.length < 2) height = width;
		if (arguments.length < 3) scale_up = false;

		var nw, nh, r;
		resize_max = [width, height, scale_up];
		r = getWidth()/getHeight();
		nw = width;
		nh = nw/r;
		if (nh > height) {
			nh = height;
			nw = nh * r;
		}
		if (!scale_up) {
			if (nw > getWidth()) return;
			if (nh > getHeight()) return;
		}
		setWidth(nw);
		setHeight(nh);
	}
	public function clearMaxSize() { resize_max = false; }

	/**
		Proportionally scales a movieclip to a max width and height.
		Allows the overflow to stick out to be cropped.

		@param  width Minimum width.
		@param  height Minimum height.
	*/
	public function cropTo(width, height, scale_up) {
		if (arguments.length < 2) height = width;
		if (arguments.length < 3) scale_up = false;

		var nw, nh, r;
		resize_crop = [width, height, scale_up];

		r = getWidth()/getHeight();
		nw = width;
		nh = nw/r;
		if (nh < height) {
			nh = height;
			nw = nh * r;
		}
		if (!scale_up) {
			if (nw > getWidth()) return;
			if (nh > getHeight()) return;
		}
		setWidth(nw);
		setHeight(nh);
	}
	public function clearCrop() { resize_crop = false; }
	
	/**
		Sets the x and y scale.

		@param  val new scale
	*/
	public function setScale(val) {
		_xscale = val;
		_yscale = val;
	}
	
	/**
		Centers the img_mc.

	*/
	public function centerContent (){
		content._x = 0 - (content._width * .5)
		content._y = 0 - (content._height * .5)
	};

// ===========================================================
// - LOADING
// ===========================================================
	/**
		Loads an asset into the clip.

		@param  newurl URL of the asset
	*/
	public function load(newurl) {
		//trace("LoadView: load "+newurl);

		// if there is no img_mc, create one
		if (img_mc == false) createEmptyMovieClip('img_mc', 1);

		// clear old
		unload();
		
		// save new
		theurl = newurl;
		
		// grab the extension
		type = newurl.substr(newurl.lastIndexOf('.')+1);
		
		// center the progress if need be
		if (autoCenter) {
			getProgressClip()._x = 0;
			getProgressClip()._y = 0;
		}
		
		// load new
		loader.loadClip(theurl, content);
	}

	public function unload() {
		loader.unloadClip(content);
		setScale(100);
		this.broadcastMessage("onUnLoad", this);
	}
	
	public function onLoadStart(clip) {
		getProgressClip().setValue(0);
		getProgressClip().startAnimation();
	}


	public function onLoadProgress(clip, loadedBytes, totalBytes) {
		getProgressClip().setTotal(totalBytes);
		getProgressClip().setValue(loadedBytes);
		getProgressClip().update();
	}
	
	public function onLoadComplete(clip) {
		// stop progress ani
		getProgressClip().stopAnimation();
	}
	
	public function onLoadInit(clip) {
		// crop/resize as needed
		if (resize_crop) {
			cropTo(resize_crop[0], resize_crop[1], resize_crop[2]);
		} else if (resize_max) {
			setMaxSize(resize_max[0], resize_max[1], resize_max[2]);
		}
		
		// if need be call the method to center
		if (autoCenter) centerContent();
		
		// tell the  world
		this.broadcastMessage("onLoad", this);
	}
	
	public function onLoadError(clip, errorCode) {
		// TODO: Throw
		trace('');
		trace('+-----------------------------------------------+');
		trace ("ERROR: " + errorCode);
		trace ("Failed to load: " + theurl);
		trace ("	Into: " + clip);
		trace('+-----------------------------------------------+');
		trace('');
	}
}